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

Some Miscellaneous Examples of the Normal (Gaussian) Distribution

Boost , Math Toolkit 2.5.0 , Normal Distribution 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

Образцовая программа normal_misc_examples.cpp иллюстрирует их использование.

Traditional Tables

Во-первых, некоторые из них должны включать в себя доступ к нормальному распределению (и, конечно же, к некоторому выходу std).

#include <boost/math/distributions/normal.hpp> // for normal_distribution
  using boost::math::normal; // typedef provides default type is double.
#include <iostream>
  using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
#include <iomanip>
  using std::setw; using std::setprecision;
#include <limits>
  using std::numeric_limits;
int main()
{
  cout << "Example: Normal distribution, Miscellaneous Applications.";
  try
  {
    { // Traditional tables and values.

Начнем с печати традиционных таблиц.

double step = 1.; // in z
double range = 4; // min and max z = -range to +range.
int precision = 17; // traditional tables are only computed to much lower precision.
// but std::numeric_limits<double>::max_digits10; on new Standard Libraries gives
// 17, the maximum number of digits that can possibly be significant.
// std::numeric_limits<double>::digits10; == 15 is number of guaranteed digits,
// the other two digits being 'noisy'.
// Construct a standard normal distribution s
  normal s; // (default mean = zero, and standard deviation = unity)
  cout << "Standard normal distribution, mean = "<< s.mean()
    << ", standard deviation = " << s.standard_deviation() << endl;

Функция распределения вероятностей (pdf).

cout << "Probability distribution function values" << endl;
cout << "  z " "      pdf " << endl;
cout.precision(5);
for (double z = -range; z < range + step; z += step)
{
  cout << left << setprecision(3) << setw(6) << z << " "
    << setprecision(precision) << setw(12) << pdf(s, z) << endl;
}
cout.precision(6); // default

А область под нормальной кривой от -∞ до z, кумулятивная функция распределения (cdf).

// For a standard normal distribution
cout << "Standard normal mean = "<< s.mean()
  << ", standard deviation = " << s.standard_deviation() << endl;
cout << "Integral (area under the curve) from - infinity up to z " << endl;
cout << "  z " "      cdf " << endl;
for (double z = -range; z < range + step; z += step)
{
  cout << left << setprecision(3) << setw(6) << z << " "
    << setprecision(precision) << setw(12) << cdf(s, z) << endl;
}
cout.precision(6); // default

И все это вы можете сделать с помощью наноскопического объема работы по сравнению с командой человеческих компьютеров , работающей с Милтоном Абрамовичем и Ирен Стэген в Национальном бюро стандартов США (сейчас NIST). Начиная с 1938 года, их «Справочник математических функций с формулами, графиками и математическими таблицами» был опубликован в 1964 году и с тех пор неоднократно переиздавался. (Основная замена запланирована по адресу Цифровая библиотека математических функций).

Прекрасная печать традиционного 2-мерного стола остается в качестве упражнения для студента, но зачем беспокоиться теперь, когда математический инструментарий позволяет писать

double z = 2.;
cout << "Area for z = " << z << " is " << cdf(s, z) << endl; // to get the area for z.

Соответственно, мы можем получить традиционные «критические» значения для уровней значимости. Для уровня уверенности 95% уровень значимости, обычно называемый альфа, составляет 0,05 = 1 - 0,95 (для одностороннего теста), поэтому мы можем написать:

  cout << "95% of area has a z below " << quantile(s, 0.95) << endl;
// 95% of area has a z below 1.64485

двухсторонний тест (сравнение двух уровней, а не односторонний тест)

  cout << "95% of area has a z between " << quantile(s, 0.975)
    << " and " << -quantile(s, 0.975) << endl;
// 95% of area has a z between 1.95996 and -1.95996

Во-первых, определите таблицу уровней значимости: это вероятности того, что истинная частота возникновения лежит за пределами вычисленного интервала.

Удобно иметь альфа-уровень для вероятности того, что z лежит за пределами одного стандартного отклонения. Это не будет какое-то красивое аккуратное число, как 0,05, но мы можем легко рассчитать его,

double alpha1 = cdf(s, -1) * 2; // 0.3173105078629142
cout << setprecision(17) << "Significance level for z == 1 is " << alpha1 << endl;

и место в нашем наборе любимых альфа-значений.

double alpha[] = {0.3173105078629142, // z for 1 standard deviation.
  0.20, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };

Значение уверенности как % составляет (1 - альфа) * 100 (поэтому альфа 0,05 == 95% уверенности), что истинная частота возникновения лежит внутри расчетного интервала.

cout << "level of significance (alpha)" << setprecision(4) << endl;
cout << "2-sided       1 -sided          z(alpha) " << endl;
for (int i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
{
  cout << setw(15) << alpha[i] << setw(15) << alpha[i] /2 << setw(10) << quantile(complement(s,  alpha[i]/2)) << endl;
  // Use quantile(complement(s, alpha[i]/2)) to avoid potential loss of accuracy from quantile(s,  1 - alpha[i]/2)
}
cout << endl;

Обратите внимание на различие между односторонним (также называемым однохвостым), где мы используем > или < тест (и не оба) и рассматриваем область хвоста (интегральную) от z до +∞ и двухсторонним тестом, где мы используем два > и < тесты, и, таким образом, рассматриваем два хвоста, от -∞ до z низкого и z высокого до +∞.

Таким образом, 2-сторонние значения альфа[i] вычисляются с использованием альфа[i]/2.

Если рассматривать простой пример альфа = 0,05, то для двухстороннего теста нижняя область хвоста от -∞ до -1,96 составляет 0,025 (альфа/2), а верхняя область хвоста от +z до +1,96 также составляет 0,025 (альфа/2), а область между -1,96 до 12,96 - альфа = 0,95. и сумма двух хвостов составляет 0,025 + 0,025 = 0,05,

Standard deviations either side of the Mean

Вооружившись функцией кумулятивного распределения, мы можем легко рассчитать легко запоминаемую пропорцию значений, которые лежат в пределах 1, 2 и 3 стандартных отклонений от среднего.

cout.precision(3);
cout << showpoint << "cdf(s, s.standard_deviation()) = "
  << cdf(s, s.standard_deviation()) << endl;  // from -infinity to 1 sd
cout << "cdf(complement(s, s.standard_deviation())) = "
  << cdf(complement(s, s.standard_deviation())) << endl;
cout << "Fraction 1 standard deviation within either side of mean is "
  << 1 -  cdf(complement(s, s.standard_deviation())) * 2 << endl;
cout << "Fraction 2 standard deviations within either side of mean is "
  << 1 -  cdf(complement(s, 2 * s.standard_deviation())) * 2 << endl;
cout << "Fraction 3 standard deviations within either side of mean is "
  << 1 -  cdf(complement(s, 3 * s.standard_deviation())) * 2 << endl;

Для полезной точности 1, 2 & 3 процента составляют 68, 95 и 99,7, и их стоит запомнить как полезные «правила большого пальца», как, например, в стандартном отклонении :

Fraction 1 standard deviation within either side of mean is 0.683
Fraction 2 standard deviations within either side of mean is 0.954
Fraction 3 standard deviations within either side of mean is 0.997

Конечно, мы могли бы получить некоторые действительно точные значения для этих доверительных интервалов . использование cout.precision(15);

Fraction 1 standard deviation within either side of mean is 0.682689492137086
Fraction 2 standard deviations within either side of mean is 0.954499736103642
Fraction 3 standard deviations within either side of mean is 0.997300203936740

Но прежде чем вы будете слишком взволнованы этой впечатляющей точностью, не забывайте, что интервалы доверия стандартного отклонения удивительно широки, особенно если вы оценили стандартное отклонение от нескольких измерений.

Some simple examples
Life of light bulbs

Примеры из K. Krishnamoorthy, Handbook of Statistical Distributions with Applications, ISBN 1 58488 635 8, page 125... реализованы с использованием библиотеки Math Toolkit.

Вот несколько очень простых примеров:

// K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
 // ISBN 1 58488 635 8, page 125, example 10.3.5

Средняя продолжительность жизни 100 Вт ламп составляет 1100 ч со стандартным отклонением 100 ч. Предполагая, возможно, с небольшим количеством доказательств и большой верой, что распределение является нормальным, мы строим нормальное распределение, называемое bulbs с этими значениями:

double mean_life = 1100.;
double life_standard_deviation = 100.;
normal bulbs(mean_life, life_standard_deviation);
double expected_life = 1000.;

Мы можем использовать функцию кумулятивного распределения для прогнозирования фракций (или процентов, если * 100), которые будут длиться различные жизни.

cout << "Fraction of bulbs that will last at best (<=) " // P(X <= 1000)
  << expected_life << " is "<< cdf(bulbs, expected_life) << endl;
cout << "Fraction of bulbs that will last at least (>) " // P(X > 1000)
  << expected_life << " is "<< cdf(complement(bulbs, expected_life)) << endl;
double min_life = 900;
double max_life = 1200;
cout << "Fraction of bulbs that will last between "
  << min_life << " and " << max_life << " is "
  << cdf(bulbs, max_life)  // P(X <= 1200)
   - cdf(bulbs, min_life) << endl; // P(X <= 900)
[Note] Note

Реальные жизненные неудачи часто очень абнормальны, со значительным числом, которое «мертво по прибытию» или терпит неудачу очень рано в их жизни: жизнь выживших после «ранней смертности» может быть хорошо описана нормальным распределением.

How many onions?

Еженедельный спрос на 5 фунтов лука в магазине обычно распределяется со средним значением 140 мешков и стандартным отклонением 10.

double mean = 140.; // sacks per week.
double standard_deviation = 10;
normal sacks(mean, standard_deviation);
double stock = 160.; // per week.
cout << "Percentage of weeks overstocked "
  << cdf(sacks, stock) * 100. << endl; // P(X <=160)
// Percentage of weeks overstocked 97.7

Там будет много луковиц! Таким образом, мы можем сказать, какой уровень акций будет удовлетворять спрос в 95% недель.

double stock_95 = quantile(sacks, 0.95);
cout << "Store should stock " << int(stock_95) << " sacks to meet 95% of demands." << endl;

И легко оценить, как удовлетворить 80% спроса, а отходов еще меньше.

double stock_80 = quantile(sacks, 0.80);
cout << "Store should stock " << int(stock_80) << " sacks to meet 8 out of 10 demands." << endl;
Packing beef

Машина должна упаковывать 3 кг говядины на упаковку. За длительный период времени установлено, что средний упакованный вес составил 3 кг при стандартном отклонении 0,1 кг. Предполагая, что упаковка обычно распределена, можно найти фракцию (или %) упаковок, которые весят более 3,1 кг.

double mean = 3.; // kg
double standard_deviation = 0.1; // kg
normal packs(mean, standard_deviation);
double max_weight = 3.1; // kg
cout << "Percentage of packs > " << max_weight << " is "
<< cdf(complement(packs, max_weight)) << endl; // P(X > 3.1)
double under_weight = 2.9;
cout <<"fraction of packs <= " << under_weight << " with a mean of " << mean
  << " is " << cdf(complement(packs, under_weight)) << endl;
// fraction of packs <= 2.9 with a mean of 3 is 0.841345
// This is 0.84 - more than the target 0.95
// Want 95% to be over this weight, so what should we set the mean weight to be?
// KK StatCalc says:
double over_mean = 3.0664;
normal xpacks(over_mean, standard_deviation);
cout << "fraction of packs >= " << under_weight
<< " with a mean of " << xpacks.mean()
  << " is " << cdf(complement(xpacks, under_weight)) << endl;
// fraction of packs >= 2.9 with a mean of 3.06449 is 0.950005
double under_fraction = 0.05;  // so 95% are above the minimum weight mean - sd = 2.9
double low_limit = standard_deviation;
double offset = mean - low_limit - quantile(packs, under_fraction);
double nominal_mean = mean + offset;
normal nominal_packs(nominal_mean, standard_deviation);
cout << "Setting the packer to " << nominal_mean << " will mean that "
  << "fraction of packs >= " << under_weight
  << " is " << cdf(complement(nominal_packs, under_weight)) << endl;

Установка упаковщика на 3.06449 будет означать, что доля упаковок >= 2,9 составляет 0,95.

Установка упаковщика на 3.13263 будет означать, что доля упаковок >= 2.9 составляет 0,99, но более чем удвоит среднюю потерю с 0,0644 до 0,133.

В качестве альтернативы мы могли бы инвестировать в лучший (более точный) упаковщик с более низким стандартным отклонением.

Чтобы оценить, насколько лучше (насколько меньше стандартное отклонение) это должно быть, нам нужно получить 5% квантиль, чтобы быть расположенным на пределе ниже веса, 2,9

double p = 0.05; // wanted p th quantile.
cout << "Quantile of " << p << " = " << quantile(packs, p)
  << ", mean = " << packs.mean() << ", sd = " << packs.standard_deviation() << endl; //

Количественное значение 0,05 = 2.83551, среднее = 3, sd = 0,1

При текущем упаковщике (среднее значение = 3, sd = 0,1) 5% квантиле составляет 2,8551 кг, что немного ниже нашей цели в 2,9 кг. Поэтому мы знаем, что стандартное отклонение должно быть меньше.

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

normal pack05(mean, 0.05);
cout << "Quantile of " << p << " = " << quantile(pack05, p)
  << ", mean = " << pack05.mean() << ", sd = " << pack05.standard_deviation() << endl;
cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
  << " and standard deviation of " << pack05.standard_deviation()
  << " is " << cdf(complement(pack05, under_weight)) << endl;
//

Фракция упаковок >= 2,9 со средним значением 3 и стандартным отклонением 0,05 составляет 0,9772

Так что 0,05 было довольно хорошей догадкой, но мы немного превысили цель 2,9, так что стандартное отклонение может быть немного больше. Так что мы могли бы сделать больше предположений, чтобы приблизиться, скажем, увеличив до 0,06

normal pack06(mean, 0.06);
cout << "Quantile of " << p << " = " << quantile(pack06, p)
  << ", mean = " << pack06.mean() << ", sd = " << pack06.standard_deviation() << endl;
cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
  << " and standard deviation of " << pack06.standard_deviation()
  << " is " << cdf(complement(pack06, under_weight)) << endl;

Фракция упаковок >= 2,9 со средним значением 3 и стандартным отклонением 0,06 составляет 0,9522

Теперь мы действительно приближаемся, но для правильного выполнения работы мы могли бы использовать метод поиска корней, например, инструменты, предоставленные и используемые в другом месте, в Math Toolkit, см. поиск корней без производных .

Но в этом нормальном случае распределения мы могли бы быть еще умнее и произвести прямой расчет.

normal s; // For standard normal distribution,
double sd = 0.1;
double x = 2.9; // Our required limit.
// then probability p = N((x - mean) / sd)
// So if we want to find the standard deviation that would be required to meet this limit,
// so that the p th quantile is located at x,
// in this case the 0.95 (95%) quantile at 2.9 kg pack weight, when the mean is 3 kg.
double prob =  pdf(s, (x - mean) / sd);
double qp = quantile(s, 0.95);
cout << "prob = " << prob << ", quantile(p) " << qp << endl; // p = 0.241971, quantile(p) 1.64485
// Rearranging, we can directly calculate the required standard deviation:
double sd95 = std::abs((x - mean)) / qp;
cout << "If we want the "<< p << " th quantile to be located at "
  << x << ", would need a standard deviation of " << sd95 << endl;
normal pack95(mean, sd95);  // Distribution of the 'ideal better' packer.
cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
  << " and standard deviation of " << pack95.standard_deviation()
  << " is " << cdf(complement(pack95, under_weight)) << endl;
// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0608 is 0.95

Обратите внимание, что эти два обманчиво простых вопроса (мы переполняем или измеряем лучше) на самом деле очень распространены. Вес говядины может быть заменен измерением более или менее чего-либо. Но вычисления основаны на точности стандартного отклонения — то, что почти всегда менее хорошо, чем мы могли бы пожелать, особенно если основываться на нескольких измерениях.

Length of bolts

Затвор можно использовать, если он имеет длину от 3,9 до 4,1. Из большой партии болтов образец 50 показывает среднюю длину 3,95 со стандартным отклонением 0,1. При нормальном распределении какая пропорция пригодна для использования? Истинное среднее значение выборки неизвестно, но мы можем использовать среднее значение выборки и стандартное отклонение, чтобы найти приблизительные решения.

    normal bolts(3.95, 0.1);
    double top = 4.1;
    double bottom = 3.9;
cout << "Fraction long enough [ P(X <= " << top << ") ] is " << cdf(bolts, top) << endl;
cout << "Fraction too short [ P(X <= " << bottom << ") ] is " << cdf(bolts, bottom) << endl;
cout << "Fraction OK  -between " << bottom << " and " << top
  << "[ P(X <= " << top  << ") - P(X<= " << bottom << " ) ] is "
  << cdf(bolts, top) - cdf(bolts, bottom) << endl;
cout << "Fraction too long [ P(X > " << top << ") ] is "
  << cdf(complement(bolts, top)) << endl;
cout << "95% of bolts are shorter than " << quantile(bolts, 0.95) << endl;

PrevUpHomeNext

Статья Some Miscellaneous Examples of the Normal (Gaussian) Distribution раздела Math Toolkit 2.5.0 Normal Distribution Examples может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Normal Distribution Examples ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:54:05/0.0075249671936035/0