在 C++ 中使用高斯概率密度函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10847007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using the gaussian probability density function in C++
提问by shn
First, is this the correct C++ representation of the pdf gaussian function ?
首先,这是 pdf 高斯函数的正确 C++ 表示吗?
float pdf_gaussian = ( 1 / ( s * sqrt(2*M_PI) ) ) * exp( -0.5 * pow( (x-m)/s, 2.0 ) );
Second, does it make sense of we do something like this ?
其次,我们这样做有意义吗?
if(pdf_gaussian < uniform_random())
do something
else
do other thing
EDIT:An example of what exactly are you trying to achieve:
编辑:您究竟想实现什么的一个例子:
Say I have a data called Y1. Then a new data called Xi arrive. I want to see if I should associated Xi to Y1 or if I should keep Xi as a new data data that will be called Y2. This is based on the distance between the new data Xi and the existing data Y1. If Xi is "far" from Y1 then Xi will not be associated to Y1, otherwise if it is "not far", it will be associated to Y1. Now I want to model this "far" or "not far" using a gaussian probability based on the mean and stdeviation of distances between Y and the data that where already associated to Y in the past.
假设我有一个名为 Y1 的数据。然后一个名为 Xi 的新数据到达。我想看看我是否应该将 Xi 与 Y1 相关联,或者是否应该将 Xi 作为将称为 Y2 的新数据数据保留。这是基于新数据Xi和现有数据Y1之间的距离。如果Xi 离Y1“远”,那么Xi 将不会关联到Y1,否则如果它“不远”,它将关联到Y1。现在我想使用基于 Y 和过去已经与 Y 关联的数据之间距离的均值和标准偏差的高斯概率来模拟这个“远”或“不远”。
采纳答案by ev-br
yes. boost::random
has gaussian distribution.
是的。boost::random
呈高斯分布。
See, for example, this question: How to use boost normal distribution classes?
例如,请参阅这个问题:如何使用 boost 正态分布类?
As an alternative, there's a standard way of converting two uniformly distributed random numbers into two normally distributed numbers.
作为替代方案,有一种标准方法可以将两个均匀分布的随机数转换为两个正态分布的数。
See, e.g. this question: Generate random numbers following a normal distribution in C/C++
参见,例如这个问题:Generate random numbers following an normal distribution in C/C++
In response to your last edit (note that the question is completely different as edited, hence my answer to an original one is irrelevant). I think you'd better off first formulating for yourself what exactly do you mean to mean by "modelling far or not far using a gaussian distribution". Then reformulate that understanding in math terms and only then start programming. As it stands, I think the problem is underspecified.
回应您上次编辑(请注意,问题与编辑时完全不同,因此我对原始问题的回答无关紧要)。我认为您最好先为自己制定“使用高斯分布建模远或不远”的确切含义。然后用数学术语重新表述这种理解,然后才开始编程。就目前而言,我认为问题没有具体说明。
回答by Alexandre C.
Technically,
从技术上讲,
float pdf_gaussian = ( 1 / ( s * sqrt(2*M_PI) ) ) * exp( -0.5 * pow( (x-m)/s, 2.0 ) );
is not incorrect, but can be improved.
没有错,但可以改进。
First, 1 / sqrt(2 Pi)
can be precomputed, and using pow
with integers is not a good idea: it may use exp(2 * log x)
or a routine specialized for floating point exponents instead of simply x * x
.
首先,1 / sqrt(2 Pi)
可以预先计算,并且pow
与整数一起使用不是一个好主意:它可能使用exp(2 * log x)
或 专门用于浮点指数的例程而不是简单的x * x
。
Example better code:
示例更好的代码:
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);
}
You may want to make this a template instead of using float
:
您可能希望将此作为模板而不是使用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);
}
this allows you to use normal_pdf
on double
arguments also (it is not that much more generic though). There are caveats with the last code, namely that you have to beware not using it with integers (there are workarounds, but this makes the routine more verbose).
这使您可以使用normal_pdf
上double
也争论(它不是更通用虽然)。最后一个代码有一些警告,即您必须注意不要将它与整数一起使用(有解决方法,但这会使例程更加冗长)。
回答by Totero
Use Box-Muller transform. This creates values with a normal/gaussian distribution.
使用 Box-Muller 变换。这将创建具有正态/高斯分布的值。
http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution
http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution
http://en.wikipedia.org/wiki/Box_Muller_transform
http://en.wikipedia.org/wiki/Box_Muller_transform
It's not very complex to code using math libraries.
使用数学库进行编码并不是很复杂。
eg.
例如。
Generate 2 uniform numbers, use them to get two normally distributed numbers. Then Return one and save the other so that you have it for your 'next' request of a random number.
生成2个统一数,用它们得到两个正态分布的数。然后返回一个并保存另一个,以便您将其用于“下一个”随机数请求。