Как использовать boost нормальные классы распространения? - PullRequest
24 голосов
/ 16 января 2010

Я пытаюсь использовать boost :: normal_distribution для генерации нормального распределения со средним 0 и сигмой 1.

Следующий код не работает, так как некоторые значения превышают -1 и превышают1 (и не должно быть).Не могли бы вы указать, что я делаю неправильно?

#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>

int main()
{
  boost::mt19937 rng; // I don't seed it on purpouse (it's not relevant)

  boost::normal_distribution<> nd(0.0, 1.0);

  boost::variate_generator<boost::mt19937&, 
                           boost::normal_distribution<> > var_nor(rng, nd);

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

Результат на моей машине:

0.213436
-0.49558
1.57538
-1.0592
1.83927
1.88577
0.604675
-0.365983
-0.578264
-0.634376

Как видите, все значения не между -1 и 1.

Спасибо всем заранее!

РЕДАКТИРОВАТЬ : Это то, что происходит, когда у вас есть крайние сроки и вы избегаете изучения теории, прежде чем приступить к практике.

Ответы [ 2 ]

30 голосов
/ 16 января 2010

Следующий код не работает, так как некоторые значения превышают -1 и 1 (и не должны быть). Не могли бы вы указать, что я делаю неправильно?

Нет, это неправильное понимание стандартного отклонения (второй параметр в конструкторе 1 ) нормального распределения.

Нормальное распределение - это знакомая кривая колокола. Эта кривая эффективно говорит вам распределение значений. Значения, близкие к тому, где пики кривой колокола более вероятны, чем значения далеко (хвост распределения).

Стандартное отклонение показывает, насколько разбросаны значения. Чем меньше число, тем более концентрированные значения находятся около среднего значения. Чем больше число, тем менее сконцентрированные значения находятся около среднего значения. На изображении ниже вы видите, что красная кривая имеет дисперсию (дисперсия является квадратом стандартного отклонения) 0,2. Сравните это с зеленой кривой, которая имеет то же среднее значение, но дисперсию 1,0. Вы можете видеть, что значения в зеленой кривой более разбросаны по отношению к красной кривой. Фиолетовая кривая имеет дисперсию 5,0, а значения еще более разбросаны.

Итак, это объясняет, почему значения не ограничиваются [-1, 1]. Однако интересно, что 68% значений всегда находятся в пределах одного стандартного отклонения от среднего. Итак, в качестве интересного теста для себя напишите программу, которая выводит большое количество значений из нормального распределения со средним 0 и дисперсией 1 и подсчитывает число, которое находится в пределах одного стандартного отклонения от среднего. Вы должны получить число, близкое к 68% (68.2689492137%, чтобы быть немного более точным).

alt text

1 : из буста документация :

normal_distribution(RealType mean = 0, RealType sd = 1);

Создает нормальное распределение со средним средним и стандартным отклонением sd.

8 голосов
/ 16 января 2010

Вы не делаете ничего плохого. Для нормального распределения сигма определяет стандарт отклонение, а не диапазон. Если вы генерируете достаточно образцов, вы увидите, что только около 68% из них лежат в диапазоне [среднее - сигма, среднее + сигма], около 95% в пределах 2 сигма, и более 99% в течение 3 сигм.

...