10

首先,这是 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

4 回答 4

11

从技术上讲,

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)或专门用于浮点指数的例程而不是简单的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_pdfdouble参数上使用(虽然它不是那么通用)。最后一个代码有一些注意事项,即您必须小心不要将它与整数一起使用(有一些变通方法,但这会使例程更加冗长)。

于 2012-06-01T10:07:34.667 回答
2

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

例如,请参阅这个问题:如何使用升压正态分布类?

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

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

作为对您上次编辑的回应(请注意,问题与已编辑完全不同,因此我对原始问题的回答是无关紧要的)。我认为您最好先自己制定“使用高斯分布建模远或不远”的确切含义。然后用数学术语重新表达这种理解,然后才开始编程。就目前而言,我认为问题未得到充分说明。

于 2012-06-01T08:40:29.017 回答
2

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

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

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

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

例如。

生成2个均匀数,用它们得到两个正态分布数。然后返回一个并保存另一个,以便您将它用于“下一个”随机数请求。

于 2012-06-01T08:47:33.493 回答
-1

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

于 2012-06-01T10:20:55.663 回答