Во-первых, нам нужно, чтобы некоторые из них включали доступ кнормальному распределению, алгоритмам для поиска масштаба (и, конечно, некоторый вывод std).
#include <boost/math/distributions/normal.hpp>
using boost::math::normal;
#include <boost/math/distributions/find_scale.hpp>
using boost::math::find_scale;
using boost::math::complement;
using boost::math::policies::policy;
#include <iostream>
using std::cout; using std::endl;
#include <iomanip>
using std::setw; using std::setprecision;
#include <limits>
using std::numeric_limits;
Для этого примера мы будем использовать стандартНормальное распределение, с нулевым местоположением (средним) и стандартным отклонением (масштабным) единством. Удобно, что это также по умолчанию для конструктора этой реализации.
normal N01;
double sd = 1.;
Предположим, что мы хотим найти другое нормальное распределение со стандартным отклонением, так что только доля р (здесь 0,001 или 0,1%) ниже определенного выбранного предела (здесь -2. стандартные отклонения).
double z = -2.;
double p = 0.001;
cout << "Normal distribution with mean = " << N01.location()
<< ", standard deviation " << N01.scale()
<< ", has " << "fraction <= " << z
<< ", p = " << cdf(N01, z) << endl;
cout << "Normal distribution with mean = " << N01.location()
<< ", standard deviation " << N01.scale()
<< ", has " << "fraction > " << z
<< ", p = " << cdf(complement(N01, z)) << endl;
Normal distribution with mean = 0 has fraction <= -2, p = 0.0227501
Normal distribution with mean = 0 has fraction > -2, p = 0.97725
Отмечая, что p = 0,02 вместо нашей цели 0,001, мы можем теперь использоватьfind_scale
, чтобы дать новое стандартное отклонение.
double l = N01.location();
double s = find_scale<normal>(z, p, l);
cout << "scale (standard deviation) = " << s << endl;
который выводит:
scale (standard deviation) = 0.647201
Показано, что необходимо уменьшить стандартное отклонение от 1,0 до 0,65.
Затем мы можем проверить, что мы достигли нашей цели, построив новое распределение с новым стандартным отклонением (но тем же нулевым средним):
normal np001pc(N01.location(), s);
И перерасчет доли ниже (и выше) выбранного нами предела.
cout << "Normal distribution with mean = " << l
<< " has " << "fraction <= " << z
<< ", p = " << cdf(np001pc, z) << endl;
cout << "Normal distribution with mean = " << l
<< " has " << "fraction > " << z
<< ", p = " << cdf(complement(np001pc, z)) << endl;
Normal distribution with mean = 0 has fraction <= -2, p = 0.001
Normal distribution with mean = 0 has fraction > -2, p = 0.999
Мы также можем контролировать политику обработки различных ошибок. Например, мы можем определить новую (возможно, неразумную) политику, чтобы игнорировать ошибки домена (плохие аргументы).
Если мы не используем ускорение::math namespace, нам понадобится:
using boost::math::policies::policy;
using boost::math::policies::domain_error;
using boost::math::policies::ignore_error;
Использование типдефа удобно, особенно если он используется повторно, хотя и не требуется, как показывают различные примеры ниже.
typedef policy<domain_error<ignore_error> > ignore_domain_policy;
l = find_scale<normal>(z, p, l, ignore_domain_policy());
l = find_scale<normal>(z, p, l, policy<>());
l = find_scale<normal>(z, p, l, boost::math::policies::policy<>());
l = find_scale<normal>(z, p, l, policy<domain_error<ignore_error> >());
Если мы хотим выразить вероятность, скажем 0,999, что является дополнением,1-p
мы даже не должны думать о написаниинайти_шкалу<нормально>z,1-p,,,
, но использоватьдополняетверсию (см.почему дополняет?.
z = -2.;
double q = 0.999;
sd = find_scale<normal>(complement(z, q, l));
normal np95pc(l, sd);
cout << "Normal distribution with mean = " << l << " has "
<< "fraction <= " << z << " = " << cdf(np95pc, z) << endl;
cout << "Normal distribution with mean = " << l << " has "
<< "fraction > " << z << " = " << cdf(complement(np95pc, z)) << endl;
К сожалению, слишком легко получить вероятность неправильно, когда вы можете получить такое предупреждение:
Message from thrown exception was:
Error in function boost::math::find_scale<Dist, Policy>(complement(double, double, double, Policy)):
Computed scale (-0.48043523852179076) is <= 0! Was the complement intended?
Политика обработки ошибок по умолчанию заключается в том, чтобы исключить это сообщение, но если вы выбрали политику, чтобы игнорировать ошибку, отрицательная шкала тихо возвращается.
См.find_scale_example.cppдля полного исходного кода: вывод программы выглядит следующим образом:
Example: Find scale (standard deviation).
Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725
scale (standard deviation) = 0.647201
Normal distribution with mean = 0 has fraction <= -2, p = 0.001
Normal distribution with mean = 0 has fraction > -2, p = 0.999
Normal distribution with mean = 0.946339 has fraction <= -2 = 0.001
Normal distribution with mean = 0.946339 has fraction > -2 = 0.999