C ++ TR1:如何使用normal_distribution?

时间:2022-04-04 00:51:13

I'm trying to use the C++ STD TechnicalReport1 extensions to generate numbers following a normal distribution, but this code (adapted from this article):

我正在尝试使用C ++ STD TechnicalReport1扩展来生成正常分布后的数字,但是这段代码(改编自本文):

mt19937 eng;
eng.seed(SEED);

normal_distribution<double> dist;
// XXX if I use the one below it exits the for loop
// uniform_int<int> dist(1, 52);

for (unsigned int i = 0; i < 1000; ++i) {
  cout << "Generating " << i << "-th value" << endl;
  cout << dist(eng) << endl;
}

only prints 1 "Generating..." log message, then never exits the for loop! If I use the distribution I commented out instead, it terminates, so I'm wondering what I'm doing wrong. Any idea?

只打印1“Generating ...”日志消息,然后永远不会退出for循环!如果我使用我注释掉的发行版,它会终止,所以我想知道我做错了什么。任何的想法?

Thanks a lot!

非常感谢!

4 个解决方案

#1


This definitely would not hang the program. But, not sure if it really meets your needs.

这肯定不会挂起程序。但是,不确定它是否真的满足您的需求。

 #include <random>
 #include <iostream>

 using namespace std;

 typedef std::tr1::ranlux64_base_01 Myeng; 

 typedef std::tr1::normal_distribution<double> Mydist; 

 int main() 
 { 
      Myeng eng; 
      eng.seed(1000);
      Mydist dist(1,10); 

      dist.reset(); // discard any cached values 
      for (int i = 0; i < 10; i++)
      {
           std::cout << "a random value == " << (int)dist(eng) << std::endl; 
      }

 return (0); 
 }

#2


I have had the same issue with the code originally posted and investigated the GNU implementation of

我最初发布的代码遇到了同样的问题并调查了GNU的实现

first some observations: with g++-4.4 and using the code hangs, with g++-4.5 and using -std=c++0x (i.e. not TR1 but the real thing) above code works

首先是一些观察结果:使用g ++ - 4.4并使用代码挂起,使用g ++ - 4.5并使用-std = c ++ 0x(即不是TR1,但真实的东西)上面的代码工作

IMHO, there was a change between TR1 and c++0x with regard to adaptors between random number generation and consumption of random numbers -- mt19937 produces integers, normal_distribution consumes doubles

恕我直言,TR1和c ++ 0x之间有关于随机数生成和随机数消耗之间的适配器的变化 - mt19937产生整数,normal_distribution消耗双精度

the c++0x uses adaption automatically, the g++ TR1 code does not

c ++ 0x自动使用自适应,g ++ TR1代码没有

in order to get your code working with g++-4.4 and TR1, do the following

为了让您的代码使用g ++ - 4.4和TR1,请执行以下操作

std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();

#3


If your TR1 random number generation implementation is buggy, you can avoid TR1 by writing your own normal generator as follows.

如果您的TR1随机数生成实现有问题,您可以通过编写自己的普通生成器来避免TR1,如下所示。

Generate two uniform (0, 1) random samples u and v using any random generator you trust. Then let r = sqrt( -2 log(u) ) and return x = r sin(2 pi v). (This is called the Box-Mueller method.)

使用您信任的任何随机生成器生成两个均匀(0,1)随机样本u和v。然后让r = sqrt(-2 log(u))并返回x = r sin(2 pi v)。 (这被称为Box-Mueller方法。)

If you need normal samples samples with mean mu and standard deviation sigma, return sigma*x + mu instead of just x.

如果您需要具有平均μ和标准偏差西格玛的正常样品样品,则返回sigma * x + mu而不是x。

#4


While this appears to be a bug, a quick confirmation would be to pass the default 0.0, 1.0 parameters. normal_distribution<double>::normal_distribution() should equal normal_distribution<double>::normal_distribution(0.0, 1.0)

虽然这似乎是一个错误,但快速确认将传递默认的0.0,1.0参数。 normal_distribution :: normal_distribution()应该等于normal_distribution :: normal_distribution(0.0,1.0)

#1


This definitely would not hang the program. But, not sure if it really meets your needs.

这肯定不会挂起程序。但是,不确定它是否真的满足您的需求。

 #include <random>
 #include <iostream>

 using namespace std;

 typedef std::tr1::ranlux64_base_01 Myeng; 

 typedef std::tr1::normal_distribution<double> Mydist; 

 int main() 
 { 
      Myeng eng; 
      eng.seed(1000);
      Mydist dist(1,10); 

      dist.reset(); // discard any cached values 
      for (int i = 0; i < 10; i++)
      {
           std::cout << "a random value == " << (int)dist(eng) << std::endl; 
      }

 return (0); 
 }

#2


I have had the same issue with the code originally posted and investigated the GNU implementation of

我最初发布的代码遇到了同样的问题并调查了GNU的实现

first some observations: with g++-4.4 and using the code hangs, with g++-4.5 and using -std=c++0x (i.e. not TR1 but the real thing) above code works

首先是一些观察结果:使用g ++ - 4.4并使用代码挂起,使用g ++ - 4.5并使用-std = c ++ 0x(即不是TR1,但真实的东西)上面的代码工作

IMHO, there was a change between TR1 and c++0x with regard to adaptors between random number generation and consumption of random numbers -- mt19937 produces integers, normal_distribution consumes doubles

恕我直言,TR1和c ++ 0x之间有关于随机数生成和随机数消耗之间的适配器的变化 - mt19937产生整数,normal_distribution消耗双精度

the c++0x uses adaption automatically, the g++ TR1 code does not

c ++ 0x自动使用自适应,g ++ TR1代码没有

in order to get your code working with g++-4.4 and TR1, do the following

为了让您的代码使用g ++ - 4.4和TR1,请执行以下操作

std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();

#3


If your TR1 random number generation implementation is buggy, you can avoid TR1 by writing your own normal generator as follows.

如果您的TR1随机数生成实现有问题,您可以通过编写自己的普通生成器来避免TR1,如下所示。

Generate two uniform (0, 1) random samples u and v using any random generator you trust. Then let r = sqrt( -2 log(u) ) and return x = r sin(2 pi v). (This is called the Box-Mueller method.)

使用您信任的任何随机生成器生成两个均匀(0,1)随机样本u和v。然后让r = sqrt(-2 log(u))并返回x = r sin(2 pi v)。 (这被称为Box-Mueller方法。)

If you need normal samples samples with mean mu and standard deviation sigma, return sigma*x + mu instead of just x.

如果您需要具有平均μ和标准偏差西格玛的正常样品样品,则返回sigma * x + mu而不是x。

#4


While this appears to be a bug, a quick confirmation would be to pass the default 0.0, 1.0 parameters. normal_distribution<double>::normal_distribution() should equal normal_distribution<double>::normal_distribution(0.0, 1.0)

虽然这似乎是一个错误,但快速确认将传递默认的0.0,1.0参数。 normal_distribution :: normal_distribution()应该等于normal_distribution :: normal_distribution(0.0,1.0)