Generating number from binomial distribution using C++ TR1
Asked Answered
L

1

11

I am trying to use the following code (taken from the internet) to generate numbers from binomial distribution. It compiles but one execution it hangs. (I am using g++ on mac.)

Could someone suggest a working code to generate numbers from binomial distribution using C++ TR1 library features?

#include <tr1/random>
#include <iostream>
#include <cstdlib>

using namespace std;
using namespace std::tr1;

int main()
{
  std::tr1::mt19937 eng; 
  eng.seed(time(NULL));
  std::tr1::binomial_distribution<int, double> roll(5, 1.0/6.0);
  std::cout << roll(eng) << std::endl;
  return 0;
}
Lemniscate answered 21/2, 2013 at 22:22 Comment(8)
Did you check in which line your program hangs? (Did you use a debugger?)Sonyasoo
It hangs in the cout line. More precisely calling roll(eng) does not seem to return.Haematoxylon
Works fine using clang's C++11 std::binomial_distribution (after removing the extra template argument), FYIKenishakenison
How interesting. Seems to be a bug in the TR1 implementation. There's an infinite loop because an accumulator is -inf. I think it happens when -std::log(__urng()) draws a 0. The C++11 version uses slightly different code, which appears to avoid this problem, or at least avoid it almost surely.Gaspard
It looks like the GCC implementation is trying to be too clever. The Boost version simply performs n Bernoulli trials. I guess when n is large, that's annoying, so the GCC standard implementation uses a trick.Gaspard
@Nate How did you compile it using C++ 11? On my machine neither "g++ -std=c++0x" nor "g++ -std=c++11" works. It says "cc1plus: error: unrecognized command line option "-std=c++0x"". Thanks!Lemniscate
If your copy of gcc is too old, it might predate C++11 features. I used libc++ and macports' clang-3.2, compiled using the --stdlib=libc++ -std=c++11 flags.Kenishakenison
Using the latest gcc compiler I got the code (given below by DennisL) to work. Thanks.Lemniscate
M
1

Here is working code:

#include <iostream>
#include <random>

int main() {
  std::random_device rd;
  std::mt19937 gen(rd());
  std::binomial_distribution<> d(5, 1.0/6.0);
  std::cout << d(gen) << std::endl;
}

You can check its result here, and it works with recent GCC and Clang versions. Please note that it is generally better to use the random_device instead of time to get a seed.

Compile it with the --std=c++11.

Mclendon answered 9/3, 2013 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.