在C++11以上中在# include <random> 頭文件中包含了std::normal_distribution<>b;正態分佈函數。
當然也可以下載boost庫,裏面已經有包裝好的正態分佈函數。
1.boost庫可以在https://www.boost.org/中進行下載最新版的
2.boost庫導入C++工程的方法可以參照博客https://blog.csdn.net/loongsking/article/details/80136004
3.導入好了boost庫後示例代碼如下
#include <boost\math\distributions\normal.hpp>
#include <iostream>
#include <random>
#include <math.h>
int main() {
//std::normal_distribution<>b;
boost::math::normal_distribution<> norm(0, 1);//期望,方差
double PI = acos(-1);
std::cout<<boost::math::cdf(norm,0)<<std::endl; //0.5 概率密度值,小於0的概率
std::cout << boost::math::pdf(norm, 0) - 1 / (sqrt(2 * PI)) << std::endl; //0 正態分佈函數值
std::cout << boost::math::cdf(boost::math::complement(norm,1)) << std::endl; // 概率密度大於1的概率
std::cout << boost::math::quantile(norm, 0.5) << std::endl; //當概率密度小於0.5時對應的x值
system("pause");
return 0;
}
其中,要引入normal.hpp才能夠使用正態分佈,norm(0,1)代表(期望,方差),cdf用來求概率密度,pdf用來求正太分佈函數對應的y值。
其實手動實現標準正太分佈的概率累積函數也是可以的,也許更快,但是精度準確性有點差。我想到的累積函數是正態分佈函數的積分,思路大概就是在x=0處進行泰勒展開,展開到五六階倒數後精度可以大概到後5位小數左右。
(從其他地方拷貝過來的標準正態分佈下的概率累積代碼可以參考參考)
double phi(double x)
{
// constants
double a1 = 0.254829592;
double a2 = -0.284496736;
double a3 = 1.421413741;
double a4 = -1.453152027;
double a5 = 1.061405429;
double p = 0.3275911;
// Save the sign of x
int sign = 1;
if (x < 0)
sign = -1;
x = fabs(x)/sqrt(2.0);
// A&S formula 7.1.26
double t = 1.0/(1.0 + p*x);
double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
return 0.5*(1.0 + sign*y);
}