Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Distribution Construction Examples

Boost , Math Toolkit 2.5.0 , Worked Examples

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Структура дистрибутивов довольно отличается от некоторых других статистических библиотек, например, тех, которые написаны на менее объектно-ориентированном языке, таком как FORTRAN и C: они дают несколько аргументов для каждой свободной функции.

Повышаю. Математическая библиотека предоставляет каждый дистрибутив в качестве шаблона класса C++. Распределение строится с помощью нескольких аргументов, а затем функции члена и нечлена используются для поиска значений распределения, часто функции случайной вариации.

Для этой демонстрации сначала нам нужны некоторые включения для доступа к отрицательному биномиальному распределению (и биномиальному, бета- и гамма-распределению).

Чтобы продемонстрировать использование с высокой точностью, определяемой пользователем типа с плавающей точкой<cpp_dec_float>, нам также необходимо включить Boost. Многоточность.

#include <boost/math/distributions/negative_binomial.hpp> // for negative_binomial_distribution
  using boost::math::negative_binomial_distribution; // default type is double.
  using boost::math::negative_binomial; // typedef provides default type is double.
#include <boost/math/distributions/binomial.hpp> // for binomial_distribution.
#include <boost/math/distributions/beta.hpp> // for beta_distribution.
#include <boost/math/distributions/gamma.hpp> // for gamma_distribution.
#include <boost/math/distributions/normal.hpp> // for normal_distribution.
#include <boost/multiprecision/cpp_dec_float.hpp> // for cpp_dec_float_100

Ниже приводятся несколько примеров построения распределений:

Во-первых, отрицательное биномиальное распределение с 8 успехами и долей успеха 0,25, 25% или 1 в 4 построено следующим образом:

boost::math::negative_binomial_distribution<double> mydist0(8., 0.25);

Но это неудобно долго, поэтому у нас может возникнуть соблазн написать

using namespace boost::math;

Но это может привести к двусмысленности с именами в<std random>, так чтонамного лучше.

using boost::math::negative_binomial_distribution;

И мы все еще можем уменьшить печатание.

Поскольку подавляющее большинство приложений используют<double>точность, аргумент шаблона для дистрибутива<RealType>по умолчанию вводит<double>, поэтому мы также можем написать:

negative_binomial_distribution<> mydist9(8., 0.25); // Uses default `RealType = double`.

Но название<negative_binomial_distribution>по-прежнему неудобно длинное, поэтому для большинства распределений предусмотрено удобство<typedef>, например:

typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
[Caution] Caution

Это удобство типизациине предусмотрено, если столкновение произойдет с названием функции: в настоящее время только<beta>и<gamma>попадают в эту категорию.

После использования заявления,

using boost::math::negative_binomial;

У нас есть удобный шрифт<negative_binomial_distribution<double>>:

negative_binomial mydist(8., 0.25);

Еще несколько примеров с использованием удобного typedef:

negative_binomial mydist10(5., 0.4); // Both arguments double.

И происходит автоматическое преобразование, поэтому вы можете использовать целые числа и поплавки:

negative_binomial mydist11(5, 0.4); // Using provided typedef double, int and double arguments.

Это, вероятно, наиболее распространенное использование.

negative_binomial mydist12(5., 0.4F); // Double and float arguments.
negative_binomial mydist13(5, 1); // Both arguments integer.

Аналогично для большинства других распределений, таких как биномиал.

binomial mybinomial(1, 0.5); // is more concise than
binomial_distribution<> mybinomd1(1, 0.5);

Для случаев, когда имя распределения типдефа столкнется с математической специальной функцией (в настоящее время только бета и гамма), типдеф намеренно не предоставляется, и должна использоваться более длинная версия имени. Например, не использовать:

using boost::math::beta;
beta mybetad0(1, 0.5); // Error beta is a math FUNCTION!

Что вызывает сообщения об ошибках:

error C2146: syntax error : missing ';' before identifier 'mybetad0'
warning C4551: function call missing argument list
error C3861: 'mybetad0': identifier not found

Вместо этого вы должны использовать:

using boost::math::beta_distribution;
beta_distribution<> mybetad1(1, 0.5);

или для гамма-распределения:

gamma_distribution<> mygammad1(1, 0.5);

Мы можем, конечно, все еще предоставить тип явно таким образом:

// Explicit double precision:  both arguments are double:
negative_binomial_distribution<double>        mydist1(8., 0.25);
// Explicit float precision, double arguments are truncated to float:
negative_binomial_distribution<float>         mydist2(8., 0.25);
// Explicit float precision, integer & double arguments converted to float:
negative_binomial_distribution<float>         mydist3(8, 0.25);
// Explicit float precision, float arguments, so no conversion:
negative_binomial_distribution<float>         mydist4(8.F, 0.25F);
// Explicit float precision, integer arguments promoted to float.
negative_binomial_distribution<float>         mydist5(8, 1);
// Explicit double precision:
negative_binomial_distribution<double>        mydist6(8., 0.25);
// Explicit long double precision:
negative_binomial_distribution<long double>   mydist7(8., 0.25);

И вы можете использовать свой собственный RealType, например<boost::math::cpp_dec_float_50>(произвольный тип точности 50 десятичных цифр), тогда мы можем написать:

 using namespace boost::multiprecision;
 negative_binomial_distribution<cpp_dec_float_50>  mydist8(8, 0.25);
 // `integer` arguments are promoted to your RealType exactly, but
 // `double` argument are converted to RealType,
 // possibly losing precision, so don't write:
 negative_binomial_distribution<cpp_dec_float_50>  mydist20(8, 0.23456789012345678901234567890);
// to avoid truncation of second parameter to `0.2345678901234567`.
 negative_binomial_distribution<cpp_dec_float_50>  mydist21(8, cpp_dec_float_50("0.23456789012345678901234567890") );
 // Ensure that all potentially significant digits are shown.
 std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
 cpp_dec_float_50 x("1.23456789012345678901234567890");
 std::cout << pdf(mydist8, x) << std::endl;
showing  0.00012630010495970320103876754721976419438231705359935
[Warning] Warning

При использовании многоточности слишком легко получить случайное усечение!

Например, если вы пишете

std::cout << pdf(mydist8, 1.23456789012345678901234567890) << std::endl;

показывает 0,00012630010495970318465064569310967179576805651692929, Что не так примерно с 17-й десятичной цифрой!

Это связано с тем, что предоставленное значение усечено до<double>, фактически<doublex =1.23456789012345678901234567890;>.

Тогда теперь<doublex>переходит к функции<pdf>, и это усеченное<double>значение, наконец, повышается до<cpp_dec_float_50>.

Другой способ получить неправильный ответ — написать:

std::cout << pdf(mydist8, cpp_dec_float_50(1.23456789012345678901234567890)) << std::endl;

Правильный путь от многозначного значения строки

std::cout << pdf(mydist8, cpp_dec_float_50("1.23456789012345678901234567890")) << std::endl;
[Tip] Tip

Получение около 17 десятичных цифр, за которыми следует множество нулей, часто является признаком случайного усечения.

Default arguments to distribution constructors.

Обратите внимание, что аргументы конструктора по умолчанию приведены только для некоторых дистрибутивов. Поэтому, если вы ошибочно принимаете аргумент по умолчанию, вы получите сообщение об ошибке, например:

negative_binomial_distribution<> mydist8;
error C2512 no appropriate default constructor available.

Конструкторы по умолчанию не предусмотрены для распределения<negative binomial>, потому что трудно выбрать какие-либо разумные значения по умолчанию для этого распределения.

Для других распределений, таких как нормальное распределение, очевидно, очень полезно обеспечить «стандартные» по умолчанию для среднего (ноль) и стандартного отклонения (единство) таким образом:

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

В этом случае мы можем написать:

  using boost::math::normal;
  normal norm1;       // Standard normal distribution.
  normal norm2(2);    // Mean = 2, std deviation = 1.
  normal norm3(2, 3); // Mean = 2, std deviation = 3.
  }
  catch(std::exception &ex)
  {
    std::cout << ex.what() << std::endl;
  }
  return 0;
}  // int main()

Полезных результатов этой демонстрационной программы, конечно, нет.

См.distribution_construction.cppдля полного исходного кода.


PrevUpHomeNext

Статья Distribution Construction Examples раздела Math Toolkit 2.5.0 Worked Examples может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Worked Examples ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 06:46:18/0.005357027053833/0