How to randomly sample from a skewed gaussian distribution in boost c++?

41 Views Asked by At

I am trying to sample a skewed gaussian distribution with the Mersenne Twister pseudo-random generator. I am using boost as the skewed gaussian distribution is not implemented in in C++ standard. The code follows below:


#include <iostream>
#include <random>
#include <chrono>
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/math/distributions/skew_normal.hpp>

int main()
{

    std::random_device rd;
    std::size_t seed;
    if (rd.entropy())
      seed = rd();
    else
      seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();

      boost::mt19937 gen(seed);     
     
     double mean(10.0), std_dev(20.0), skewness(2.0);
     double sample;
     auto skew_norm_dist = boost::math::skew_normal_distribution<double>(mean, std_dev, skewness);
     boost::variate_generator<boost::mt19937&,boost::math::skew_normal_distribution<double> > var_snd(gen, skew_norm_dist);
     for(std::size_t i = 0; i < 1.0e3; ++i)
     {
      sample = var_snd();
      std::cerr<<i<<" "<<sample<<std::endl;
     }

    return 0;
}

Unfortunately I get the error:

In file included from /usr/include/boost/random.hpp:55,
                 from main_stackoverflow.cpp:4:
/usr/include/boost/random/variate_generator.hpp: In instantiation of ‘class boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>&, boost::math::skew_normal_distribution<double> >’:
main_stackoverflow.cpp:23:103:   required from here
/usr/include/boost/random/variate_generator.hpp:59:48: error: no type named ‘result_type’ in ‘class boost::math::skew_normal_distribution<double>’
   59 |     typedef typename Distribution::result_type result_type;
      |                                                ^~~~~~~~~~~
main_stackoverflow.cpp: In function ‘int main()’:
main_stackoverflow.cpp:26:23: error: no match for call to ‘(boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>&, boost::math::skew_normal_distribution<double> >) ()’
   26 |       sample = var_snd();
      |                ~~~~~~~^~

Can anybody help me? Many thanks.

1

There are 1 best solutions below

2
Caleth On

Unfortunately, the boost::math distributions don't satisfy the requirement RandomNumberDistribution. They don't provide a way of drawing a random variate from the distribution, so we can't even fix up the missing member type aliases.

The documentation even notes this:

If you want random numbers that are distributed in a specific way, for example in a uniform, normal or triangular, see Boost.Random.