Search code examples
c++exponential-distribution

How to generate random numbers with exponential distribution (with mean)?


I am trying to generate exponentially distributed random number with mean equal to 1. I know how to get random number for normal distribution with mean and standard deviation. We can get it by normal(mean, standard_deviation), but I don't know how to get random number for exponential distribution.

Can anyone help me with this?


Solution

  • With C++11 the standard actually guarantees that there is a RNG following the requirements of exponential-distribution available in the STL, and fittingly the object-type has a very descriptive name.

    The mean in an exponentially distributed random generator is calculated by the formula E[X] = 1 / lambda1.

    std::exponential_distribution has a constructor taking lambda as an argument, so we can easily create an object following your rules by calculating the value of lambda and passing this to our generator.

    std::exponential_distribution rng (1/1); // lambda = 1 / E[X]
    

    Footnotes
    1. according to en.wikipedia.org - Exponential distribution > Mean, variance, moments and median


    Distribution as readable ascii chart

    #include <iomanip>
    #include <random>
    #include <map>
    #include <iostream>
    
    int
    main (int argc, char *argv[])
    {
      double const exp_dist_mean   = 1;
      double const exp_dist_lambda = 1 / exp_dist_mean;
    
      std::random_device rd; 
    
      std::exponential_distribution<> rng (exp_dist_lambda);
      std::mt19937 rnd_gen (rd ());
    
      /* ... */
    
      std::map<int, int> result_set;
    
      for (int i =0; i < 100000; ++i)
        ++result_set[rng (rnd_gen) * 4]; 
    
      for (auto& v : result_set) {
        std::cout << std::setprecision (2) << std::fixed;
    
        std::cout << v.first/4.f << " - " << (v.first+1)/4.f << " -> ";
        std::cout << std::string (v.second/400, '.') << std::endl;
    
        if (v.second/400 == 0)
          break;
      }
    }
    

    0.00 - 0.25 -> ........................................................
    0.25 - 0.50 -> ...........................................
    0.50 - 0.75 -> .................................
    0.75 - 1.00 -> .........................
    1.00 - 1.25 -> ....................
    1.25 - 1.50 -> ...............
    1.50 - 1.75 -> ............
    1.75 - 2.00 -> .........
    2.00 - 2.25 -> .......
    2.25 - 2.50 -> .....
    2.50 - 2.75 -> ....
    2.75 - 3.00 -> ...
    3.00 - 3.25 -> ..
    3.25 - 3.50 -> ..
    3.50 - 3.75 -> .
    3.75 - 4.00 -> .
    4.00 - 4.25 -> .
    4.25 - 4.50 ->