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;
}
Kijewski
  • 25,517
  • 12
  • 101
  • 143
Madhav Jha
  • 863
  • 1
  • 8
  • 26
  • Did you check in which line your program hangs? (Did you use a debugger?) – Zeta Feb 21 '13 at 22:26
  • It hangs in the cout line. More precisely calling `roll(eng)` does not seem to return. – Kijewski Feb 21 '13 at 22:27
  • Works fine using clang's C++11 std::binomial_distribution (after removing the extra template argument), FYI – Nate Kohl Feb 21 '13 at 22:35
  • 4
    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. – Kerrek SB Feb 21 '13 at 22:36
  • 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. – Kerrek SB Feb 21 '13 at 22:38
  • @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! – Madhav Jha Feb 21 '13 at 22:45
  • 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. – Nate Kohl Feb 22 '13 at 00:45
  • Using the latest gcc compiler I got the code (given below by DennisL) to work. Thanks. – Madhav Jha Sep 20 '13 at 22:56

1 Answers1

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.

DennisL
  • 466
  • 3
  • 6