Использование Boost skew_normal_distribution

Это уже решалось ранее (Использование буста skewed_normal_distribution), но у меня возникли трудности, и предыдущий поток не включал код решения.

Я хотел бы взять пример из искаженного нормального распределения, используя функции, встроенные в библиотеку Boost

Я адаптирую код, который, как я знаю, отлично работает с normal_distribution<> класс, но когда я запускаю код, я получаю сообщение об ошибке, показанное ниже. Если бы кто-нибудь мог помочь мне с этим, я был бы очень благодарен.

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

int main() {

boost::mt19937 rng2;

boost::math::skew_normal_distribution<> snd(0.0, 1.0, 1.0);

boost::variate_generator<boost::mt19937&,
boost::math::skew_normal_distribution<> > var_snd(rng2, snd);

int i = 0; for (; i < 10; ++i)
{
double d = var_snd();
std::cout << d << std::endl;
}return 0;
}

Ошибка:

[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
In file included from /usr/include/boost/random.hpp:55:0,
from /home/jack/CLionProjects/untitled/main.cpp:1:
/usr/include/boost/random/variate_generator.hpp: In instantiation of ‘class boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32ul, 624ul, 397ul, 31ul, 2567483615u, 11ul, 4294967295u, 7ul, 2636928640u, 15ul, 4022730752u, 18ul, 1812433253u>&, boost::math::skew_normal_distribution<double> >’:
/home/jack/CLionProjects/untitled/main.cpp:13:63:   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>’
typedef typename Distribution::result_type result_type;

2

Решение

В Boost есть два разных пространства имен, которые содержат классы распространения: boost::random а также boost::math, К сожалению, эти два разных пространства имен написаны с разными целями, и поэтому базовые дистрибутивы не могут быть немедленно заменены, как вы пытаетесь сделать здесь.

Вы заметите, что нормальный класс распространения, с которого вы изначально начали, принадлежит boost::random Пространство имен. Пока skew_normal класс принадлежит boost::math Пространство имен; отсюда и несовместимость.

Если вы просто хотите создать образцы из boost::math::skew_normal Однако вы можете сделать это с помощью следующего метода (при условии, что вы используете C ++ 11):

#include <boost/math/distributions/skew_normal.hpp>

// Setup generators
std::random_device rd;
std::default_random_engine noise_generator;

// Sample from a uniform distribution i.e. [0,1)
std::uniform_real_distribution<double> uniform_dist(0,1.0);

// Take a different value every time to generate probabilities from 0 to 1
noise_generator.seed(rd());
auto probability = uniform_dist(noise_generator);

auto skew_norm_dist = boost::math::skew_normal_distribution<double>(
0, 1., 10.);

// Use the probability from the uniform distribution with the percent point
// function of the skew_normal
double skew_normal_sample_point = boost::math::quantile(skew_norm_dist, probability);
std::cout << "Sample point: " << skew_normal_sample_point << std::endl;

Здесь вы по существу генерируете значение вероятности из равномерного распределения, а затем используете это для поиска значения из skew_normal_distributionПроцентная функция.

Если вы поместите эти последние четыре строки в цикл и получите большое количество точек, например,

for(unsigned int i = 0; i < 10000; ++i)
{
noise_generator.seed(rd());
auto probability = uniform_dist(noise_generator);
double skew_normal_sample_point = boost::math::quantile(skew_norm_dist, probability);
std::cout << skew_normal_sample_point << std::endl;
}

и затем отобразите результаты в гистограмме, вы увидите, что они соответствуют искаженному нормальному распределению, которое вы создали.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]