Mustaqil ish s in C++ C++ da statistik taqsimotlar


Standart normal taqsimotni amalga oshirish


Download 0.74 Mb.
bet3/4
Sana15.06.2023
Hajmi0.74 Mb.
#1482107
1   2   3   4
Bog'liq
das oybek

Standart normal taqsimotni amalga oshirish
Birinchidan, standart normal taqsimlash uchun amalga oshirishimiz kerak bo'lgan turli usullarning formulasini qisqacha ko'rib chiqamiz. Standart normal taqsimotning ehtimollik zichligi funksiyasi quyidagicha beriladi:

Yig’indi zichlik funktsiyasi quyidagilar tomonidan beriladi:

Standart normal taqsimlashning (ehtimollik funktsiyasi deb ham ataladi) invers kümülatif zichligi funktsiyasi biroz ko'proq ishtirok etadi. Bu muayyan funktsiya uchun hech qanday analitik formula mavjud emas va shuning uchun u raqamli usullar bilan taxmin qilinishi kerak. Korn[3] da uchraydigan Beasley-Springer-Moro algoritmidan foydalanamiz. Men bu erda batafsil ta'riflamayman, chunki tafsilotlar Korn[3] ga tegishli.
Biz standart normal taqsimot bilan shug'ullanayotganimizni hisobga olsak, o'rtacha oddiygina μ=0, variance=1 va standart sapma, =1. Bosh fayl uchun amalga oshirilishi (bu yuqorida statistika.h ning davomi ) quyidagicha:
class StandardNormalDistribution : public StatisticalDistribution {
public:
StandardNormalDistribution();
virtual ~StandardNormalDistribution();


// Distribution functions
virtual double pdf(const double& x) const;
virtual double cdf(const double& x) const;


// Inverse cumulative distribution function (aka the probit function)
virtual double inv_cdf(const double& quantile) const;

// Descriptive stats
virtual double mean() const; // equal to 0
virtual double var() const; // equal to 1
virtual double stdev() const; // equal to 1


// Obtain a sequence of random draws from the standard normal distribution
virtual void random_draws(const std::vector& uniform_draws,
std::vector& dist_draws);
};
Manba fayl quyida koʻrsatilgan:
#ifndef __STATISTICS_CPP
#define __STATISTICS_CPP


#define _USE_MATH_DEFINES


#include "statistics.h"
#include


StatisticalDistribution::StatisticalDistribution() {}
StatisticalDistribution::~StatisticalDistribution() {}


// Constructor/destructor
StandardNormalDistribution::StandardNormalDistribution() {}
StandardNormalDistribution::~StandardNormalDistribution() {}


// Probability density function
double StandardNormalDistribution::pdf(const double& x) const {
return (1.0/sqrt(2.0 * M_PI)) * exp(-0.5*x*x);
}


// Cumulative density function
double StandardNormalDistribution::cdf(const double& x) const {
double k = 1.0/(1.0 + 0.2316419*x);
double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));


if (x >= 0.0) {
return (1.0 - (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum);
} else {
return 1.0 - cdf(-x);
}
}


// Inverse cumulative distribution function (aka the probit function)
double StandardNormalDistribution::inv_cdf(const double& quantile) const {
// This is the Beasley-Springer-Moro algorithm which can
// be found in Glasserman [2004]. We won't go into the
// details here, so have a look at the reference for more info
static double a[4] = { 2.50662823884,
-18.61500062529,
41.39119773534,
-25.44106049637};


static double b[4] = { -8.47351093090,
23.08336743743,
-21.06224101826,
3.13082909833};


static double c[9] = {0.3374754822726147,
0.9761690190917186,
0.1607979714918209,
0.0276438810333863,
0.0038405729373609,
0.0003951896511919,
0.0000321767881768,
0.0000002888167364,
0.0000003960315187};


if (quantile >= 0.5 && quantile <= 0.92) {
double num = 0.0;
double denom = 1.0;


for (int i=0; i<4; i++) {
num += a[i] * pow((quantile - 0.5), 2*i + 1);
denom += b[i] * pow((quantile - 0.5), 2*i);
}
return num/denom;


} else if (quantile > 0.92 && quantile < 1) {
double num = 0.0;


for (int i=0; i<9; i++) {
num += c[i] * pow((log(-log(1-quantile))), i);
}
return num;


} else {
return -1.0*inv_cdf(1-quantile);
}
}

// Expectation/mean
double StandardNormalDistribution::mean() const { return 0.0; }


// Variance
double StandardNormalDistribution::var() const { return 1.0; }


// Standard Deviation
double StandardNormalDistribution::stdev() const { return 1.0; }


// Obtain a sequence of random draws from this distribution
void StandardNormalDistribution::random_draws(const std::vector& uniform_draws,
std::vector& dist_draws) {
// The simplest method to calculate this is with the Box-Muller method,
// which has been used procedurally in many other articles on QuantStart.com

// Check that the uniform draws and dist_draws are the same size and
// have an even number of elements (necessary for B-M)
if (uniform_draws.size() != dist_draws.size()) {
std::cout << "Draws vectors are of unequal size in standard normal dist." << std::endl;
return;
}

// Check that uniform draws have an even number of elements (necessary for B-M)
if (uniform_draws.size() % 2 != 0) {
std::cout << "Uniform draw vector size not an even number." << std::endl;
return;
}


// Slow, but easy to implement
for (int i=0; i dist_draws[2*i] = sqrt(-2.0*log(uniform_draws[2*i])) * sin(2*M_PI*uniform_draws[2*i+1]);
dist_draws[2*i+1] = sqrt(-2.0*log(uniform_draws[2*i])) * cos(2*M_PI*uniform_draws[2*i+1]);
}


return;
}
#endif
Bu erda ba'zi amalga oshirishlarni qisqacha muhokama qilaman. Kümülatif taqsimlanish funksiyasi (cdf) Joshi[1] dan ko'rsatilgan. Bu yopiq shakldagi eritma emas, balki yaqinlashishdir. Inverse CDF (inv_cdf) Korndagi amalga oshirishdan to'g'ridan-to'g'ri kodlagan Beasley-Springer-Moro algoritmidan foydalanadi[3]. Shunga oʻxshash usulni Joshi[2] da uchratsa boʻladi. Algoritm yana yopiq shakl yechimiga emas, balki haqiqiy funktsiyaga yaqinlashishdir. Sonli usul random_draws. Bu holda biz Box-Muller algoritmidan foydalanamiz. Biroq, buning o'rniga biz yanada samarali Ziggurat algoritmidan foydalanishimiz mumkin edi, ammo bu keyingi maqola uchun potentsial muhokama bo'ladi!

Download 0.74 Mb.

Do'stlaringiz bilan baham:
1   2   3   4




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling