如何使用boost正态分布类?
我正在尝试使用 boost::normal_distribution 来生成均值 0 和 sigma 1 的正态分布。
以下代码不起作用,因为某些值超过或超出 -1 和 1(并且不应该)。有人可以指出我做错了什么吗?
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
int main()
{
boost::mt19937 rng; // I don't seed it on purpouse (it's not relevant)
boost::normal_distribution<> nd(0.0, 1.0);
boost::variate_generator<boost::mt19937&,
boost::normal_distribution<> > var_nor(rng, nd);
int i = 0; for (; i < 10; ++i)
{
double d = var_nor();
std::cout << d << std::endl;
}
}
我机器上的结果是:
0.213436
-0.49558
1.57538
-1.0592
1.83927
1.88577
0.604675
-0.365983
-0.578264
-0.634376
如您所见,所有值都不在 -1 和 1 之间。
提前谢谢大家!
编辑:当你有最后期限并且避免在实践之前学习理论时,就会发生这种情况。
I'm trying to use boost::normal_distribution in order to generate a normal distribution with mean 0 and sigma 1.
The following code doesn't work as some values are over or beyond -1 and 1 (and shouldn't be). Could someont point out what I am doing wrong?
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
int main()
{
boost::mt19937 rng; // I don't seed it on purpouse (it's not relevant)
boost::normal_distribution<> nd(0.0, 1.0);
boost::variate_generator<boost::mt19937&,
boost::normal_distribution<> > var_nor(rng, nd);
int i = 0; for (; i < 10; ++i)
{
double d = var_nor();
std::cout << d << std::endl;
}
}
The result on my machine is:
0.213436
-0.49558
1.57538
-1.0592
1.83927
1.88577
0.604675
-0.365983
-0.578264
-0.634376
As you can see all values are not between -1 and 1.
Thank you all in advance!
EDIT: This is what happens when you have deadlines and avoid studying the theory before doing the practice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,这是对正态分布的标准差(构造函数1中的第二个参数)的误解。
正态分布就是我们熟悉的钟形曲线。该曲线有效地告诉您值的分布。靠近钟形曲线峰值位置的值比远离钟形曲线峰值(分布尾部)的值更有可能出现。
标准差告诉您值的分布情况。数字越小,值越集中在平均值附近。数字越大,平均值附近的值越不集中。在下图中,您可以看到红色曲线的方差(方差是标准差的平方)为 0.2。将此与具有相同均值但方差为 1.0 的绿色曲线进行比较。您可以看到绿色曲线中的值相对于红色曲线更加分散。紫色曲线的方差为 5.0,并且值更加分散。
因此,这解释了为什么这些值不限于
[-1, 1]
。然而,一个有趣的事实是,68% 的值始终在平均值的一个标准差之内。因此,作为对自己的一项有趣测试,编写一个程序,从均值为 0、方差为 1 的正态分布中抽取大量值,并计算均值在一个标准差内的数量。您应该得到接近 68% 的数字(更精确一点是 68.2689492137%)。1:来自 boost 文档:
No, this is a misunderstanding of the standard deviation (the second parameter in the constructor1) of the normal distribution.
The normal distribution is the familiar bell curve. That curve effectively tells you the distribution of values. Values close to where the bell curve peaks are more likely than values far away (the tail of the distribution).
The standard deviation tells you how spread out the values are. The smaller the number, the more concentrated values are around the mean. The larger the number, the less concentrated values are around the mean. In the image below you see that the red curve has a variance (variance is the square of the standard deviation) of 0.2. Compare this to the green curve which has the same mean but a variance of 1.0. You can see that the values in the green curve are more spread out relative to the red curve. The purple curve has variance 5.0 and the values are even more spread out.
So, this explains why the values are not confined to
[-1, 1]
. It is, however, an interesting fact that 68% of the values are always within one standard deviation of the mean. So, as an interesting test for yourself write a program to draw a large number of values from a normal distribution with mean 0 and variance 1 and count the number that are within one standard deviation of the mean. You should get a number close to 68% (68.2689492137% to be a little more precise).1: From the boost documentation:
你没有做错任何事。对于正态分布,sigma 指定标准
偏差,而不是范围。如果你生成足够多的样本,你会发现只有大约
其中 68% 位于 [平均值 - 西格玛、平均值 + 西格玛] 范围内,大约 95% 在 2 西格玛内,
99%以上在3西格玛之内。
You're not doing anything wrong. For a normal distribution, sigma specifies the standard
deviation, not the range. If you generate enough samples, you will see that only about
68% of them lie in the range [mean - sigma, mean + sigma], about 95% within 2 sigma,
and more than 99% within 3 sigma.