在C ++中使用高斯概率密度函数

时间:2012-06-01 08:38:24

标签: c++ distribution probability gaussian normal-distribution

首先,这是pdf高斯函数的正确C ++表示吗?

float pdf_gaussian = ( 1 / ( s * sqrt(2*M_PI) ) ) * exp( -0.5 * pow( (x-m)/s, 2.0 ) );

第二,我们做这样的事情是否有意义?

if(pdf_gaussian < uniform_random())
   do something
else
   do other thing

编辑:您想要实现的目标的一个例子:

假设我有一个名为Y1的数据。然后一个名为Xi的新数据到达。我想知道是否应该将Xi与Y1相关联,或者是否应将Xi保留为将被称为Y2的新数据数据。这基于新数据Xi与现有数据Y1之间的距离。如果Xi与Y1“相距”,那么Xi将不与Y1相关联,否则如果它“不远”,则它将与Y1相关联。现在我想使用基于Y和过去已经与Y相关联的数据之间的距离的平均值和偏差的高斯概率来模拟这个“远”或“不远”。

4 个答案:

答案 0 :(得分:10)

从技术上讲,

float pdf_gaussian = ( 1 / ( s * sqrt(2*M_PI) ) ) * exp( -0.5 * pow( (x-m)/s, 2.0 ) );

不正确,但可以改进。

首先,1 / sqrt(2 Pi)可以预先计算,并且使用带有整数的pow不是一个好主意:它可能使用exp(2 * log x)或专门用于浮点指数的例程而不仅仅是{{ 1}}。

示例更好的代码:

x * x

您可能希望将此设为模板,而不是使用float normal_pdf(float x, float m, float s) { static const float inv_sqrt_2pi = 0.3989422804014327; float a = (x - m) / s; return inv_sqrt_2pi / s * std::exp(-0.5f * a * a); }

float

这允许您在template <typename T> T normal_pdf(T x, T m, T s) { static const T inv_sqrt_2pi = 0.3989422804014327; T a = (x - m) / s; return inv_sqrt_2pi / s * std::exp(-T(0.5) * a * a); } 参数上使用normal_pdf(虽然它不是那么通用)。最后一个代码有一些注意事项,即你必须注意不要将它与整数一起使用(有解决方法,但这会使例程更加冗长)。

答案 1 :(得分:2)

是肯定的。 boost::random具有高斯分布。

例如,请参阅此问题:How to use boost normal distribution classes?

作为替代方案,有一种将两个均匀分布的随机数转换为两个正态分布数的标准方法。

参见,例如这个问题:Generate random numbers following a normal distribution in C/C++

响应您的上次编辑(请注意,编辑时问题完全不同,因此我对原始问题的回答无关紧要)。我认为你最好首先为自己制定一个“使用高斯分布建模远远不远”的意思。然后用数学术语重新理解这种理解,然后开始编程。就目前而言,我认为问题是不明确的。

答案 2 :(得分:1)

使用Box-Muller变换。这会创建具有正态/高斯分布的值。

http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

http://en.wikipedia.org/wiki/Box_Muller_transform

使用数学库进行编码并不是很复杂。

例如

生成2个统一数字,使用它们得到两个正态分布的数字。然后返回一个并保存另一个,以便为随机号码的“下一个”请求提供它。

答案 3 :(得分:0)

从C ++ 11开始,标准头std::normal_distribution中定义的random可用于生成高斯随机样本。可以找到更多信息herein